import datetime
import os
from time import time
from docx import Document
import traceback
from colorama import init
init(autoreset=True)

#设置区
#############
path=os.getcwd()+"\\"  #数据库的路径（极其重要，未填写则默认在本文件夹下构建）
filename="error.txt"
foldername="error"
SEpa="\n"
os.chdir(path[:-1])
time_point=[0]*5
cb="ctf_base.txt"

#############

#字体颜色函数(c)
def c(color):
    if color==0:return f"\033[0m"
    elif 10<=color<20:#0黑1红2绿3黄4蓝5紫6青7白
        return f"\033[{color+20}m"
    elif 20<=color<30:#亮色
        return f"\033[{color+70}m"
    elif 40<=color<50:#下划线
        return f"\033[{color-10}m\033[4m"
    elif 50<=color<60:#下滑亮色
        return f"\033[{color+40}m\033[4m"
    elif 110<=color<120:#背景色
        return f"\033[{color-70}m"
    elif 120<=color<130:#背景亮色
        return f"\033[{color-20}m\033[4m"
    else: return "未找到颜色"

#information.txt内容
#############
information=[
f'{c(12)}路径{c(24)}：%s',
f'{c(12)}创建时间{c(24)}：%s',
f'{c(12)}最近的更新时间{c(24)}：%s',
f'{c(12)}更新次数{c(24)}：%d',
f'{c(12)}WP文件数{c(24)}：%d',
f'{c(12)}name树分支数{c(24)}：%d',
f'{c(12)}ctf树分支数{c(24)}：%d',
f'{c(12)}查询次数{c(24)}：%d',
f'{c(12)}总字数{c(24)}：%d']
#############

#日志函数(report)
def report(message):
    timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    report_message = f"{timestamp} {message}"  # 添加时间信息
    print(f"{c(15)}["+timestamp+f"] {c(22)}"+message)  # 打印报告
    with open(path+"log.txt", 'a') as f:
        f.write(report_message + "\n")


#读写文件函数(write_txt,read_txt,add_txt,op)
def write_txt(lis,file=filename):
    txt = SEpa.join(lis)
    try:
        with open(path+file, 'w') as f:
            f.write(txt)
    except UnicodeEncodeError:
        try:
            with open(path+file, 'w',encoding="utf-8") as f:
                f.write(txt)
        except UnicodeEncodeError:
            with open(path+file, 'w', encoding="utf-16") as f:
                f.write(txt)
                
def read_txt(file=filename):
    try:
        with open(path+file, 'r', encoding="utf-8") as f:
            txt = f.read()
    except UnicodeDecodeError:
        try:
            with open(path+file, 'r', encoding="utf-16") as f:
                txt = f.read()
        except UnicodeError:
            try:
                with open(path+file, 'r') as f:
                    txt = f.read()
            except UnicodeDecodeError:
                doc = Document(path+file)
                txt = SEpa.join([i.text for i in doc.paragraphs])
    return txt.split(SEpa)


def add_txt(lis,file=filename):
    txt = SEpa+SEpa.join(lis)
    try:
        with open(path+file, 'a') as f:
            f.write(txt)
    except UnicodeEncodeError:
        try:
            with open(path+file, 'a',encoding="utf-8") as f:
                f.write(txt)
        except UnicodeEncodeError:
            with open(path+file, 'a', encoding="utf-16") as f:
                f.write(txt)
        
def op(subpath):
    report("文档 %s正在打开,请稍候..."%subpath.split('\\')[-1])
    os.startfile(path+subpath)
    

#单纯只是为了去掉文件名后的".txt"(txt_out)
def txt_out(lis):
    for i in range(len(lis)):
        lis[i]=lis[i][:-4]
    return lis

#文件夹管理函数(new_folder,dir_folder,dir_file)
def new_folder(folder=foldername):
    os.makedirs(folder)

def dir_file(subpath=""):
    return os.listdir(path+subpath)

def dir_folder(subpath=""):
    file=dir_file(subpath)
    folder=[]
    for p in file:
        if os.path.isdir(subpath+p):
            folder.append(p)
    return folder


#计时函数(begin_time,end_time)
def begin_time(a):
    global time_point
    time_point[a]=time()

def end_time(a):
    return time()-time_point[a]


#初始构建WP库函数(initial)
def initial():
    root = dir_folder()
    init = {"name":["网站","比赛"],"ctf":["misc","crypto","web","pwn","reverse","mobile"]}
    for i in "name","ctf":
        write_txt(init[i],i+".txt")
    write_txt(["$"+i for i in init["ctf"]],cb)
    write_txt(["本WP库基本信息"],"information.txt")
    infor=(
path,
datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
0,0,0,0,0,0)
    for i in range(len(information)):
        add_txt([information[i]%infor[i]],"information.txt")

#WP基本信息存取函数/基本信息查看函数(infor_process,infor_view)
def info_process(infor=None):
    if infor:
        write_txt(infor[:3],"information.txt")
        infor[3]=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        infor[4]+=1
        for i in range(3,len(information)+1):
            add_txt([information[i-1]%infor[i]],"information.txt")
        #report("WP库基本信息更新完成")
        return infor
    else:
        infor=read_txt("information.txt")
        infor[3]=infor[3][1+infor[3].find("："):]
        for i in range(4,len(information)+1):
            infor[i]=int(infor[i][1+infor[i].find("："):])
        #report("WP库基本信息读取完成")
        return infor

def info_view(infor):
    for i in range(3):
        print(f"{c(13)}"+infor[i])
    for i in range(3,len(information)+1):
        print(information[i-1]%infor[i])
    print()

#四维字典与文本读写(dict_load)
def dict_load(treename,dic=None):
    spl=["\n","--","@@","**"]
    if dic:
        def cir(level,di,lis):
            if level!=3:
                for i in di:
                    lis.append(cir(level+1,di[i],[i]))
            elif di:lis.append(spl[3].join(di))
            return spl[level].join(lis)
        try:
            with open(path+treename+'.txt', 'w') as f:
                f.write(cir(0,dic,[]))
        except UnicodeEncodeError:
            try:
                with open(path+treename+'.txt', 'w',encoding="utf-8") as f:
                    f.write(cir(0,dic,[]))
            except UnicodeEncodeError:
                with open(path+file, 'a', encoding="utf-16") as f:
                    f.write(txt)
    else:
        hold=read_txt(treename+'.txt')
        def cir(level,di,lis):
            for i in lis:
                i=i.split(spl[level])
                if level==3:di[i[0]]=i[1:]
                else:di[i[0]]=cir(level+1,{},i[1:])
            return di
        dic=cir(1,{},hold)
        return dic

#目录文件获取(get_tree)
def get_tree(path=""):
    if len(path.split('\\'))==4:return dir_file(path)
    else:return {i:get_tree(path+i+"\\") for i in dir_folder(path)}

#WP库更新报告与读写(dict_check,dict_update)
def dict_check(name,ct):
    infor=info_process()
    infor[5:8]=[0,0,0]
    infor[9]=0
    #report("更新检查中...")
    begin_time(2)
    more=[[],[],[],[]]
    less=[[],[],[],[]]
    red = lambda a,b:list(set(a)-set(b))
    plus = lambda a,b:list(set(a)|set(b))
    ctf={}
    ftc={}
    def ctf_get(path,name):
        infor[5]+=1
        for m in read_txt(path+name):
            infor[9]+=len(m)
            if m and m[0]=="$":
                m=m[1:].split("-")
                if (len(m)<3 and name!=cb) or "" in m:continue
                if not m[0] in ctf:ctf[m[0]]={}
                if len(m)>1 and (not (m[1] in ctf[m[0]])):ctf[m[0]][m[1]]={}
                if len(m)>2 and (not (m[2] in ctf[m[0]][m[1]])):ctf[m[0]][m[1]][m[2]]=[]
                if len(m)==1:ctf[m[0]][name]={}
                if len(m)==2:ctf[m[0]][m[1]][name]={}
                try:ctf[m[0]][m[1]][m[2]].append(name)
                except IndexError:pass
                
                if not m[0] in ftc:ftc[m[0]]={}
                if len(m)>1 and (not (m[1] in ftc[m[0]])):ftc[m[0]][m[1]]={}
                if len(m)>2 and (not (m[2] in ftc[m[0]][m[1]])):ftc[m[0]][m[1]][m[2]]=[]
                try:ftc[m[0]][m[1]][m[2]].append(path)
                except IndexError:pass
    def ext(path,level):
        if level<2:return {i:ext(path+i+"\\",level+1) for i in dir_file(path)}
        else:
            for i in dir_file(path):ctf_get(path,i)
            return dir_file(path)
    def cir(name,level,path):
        if level==4:
            try:ctf_get(path,name)
            except FileNotFoundError:less[3].append([path,name])
        else:
            try:
                if level==3:
                    for i in plus(dir_file(path),name):
                        if i[:2]=="~$":continue
                        if i not in name:more[3].append([path,i])
                        cir(i,level+1,path)
                else:
                    for i in plus(dir_folder(path),name):
                        infor[6]+=1
                        #a=dir_folder(path+i+"\\")
                        try:cir(name[i],level+1,path+i+"\\")
                        except KeyError:more[level].append([path,i,ext(path+i+'\\',level)])
            except FileNotFoundError:
                path=path.split("\\")
                if len(path)==2:less[level-1].append(['',path[-2],name])
                else:less[level-1].append(['\\'.join(path[:-2])+"\\",path[-2],name])
    ctf_get("",cb)
    cir(name,0,"")
    name=[more,less]
    more,less=[[],[],[],[]],[[],[],[],[]]
    for i in ctf:
        if i!=cb:infor[7]+=1
        for j in ctf[i]:
            if j!=cb:infor[7]+=1
            for k in ctf[i][j]:
                if k!=cb:infor[7]+=1
    
    def circum(ct,ctf,level,path):
        if level==3:
            for i in plus(ct,ctf):
                if i not in ct:more[level].append([path,i])
                elif i not in ctf:less[level].append([path,i])
        else:    
            for i in plus(ct,ctf):
                if i==cb:continue
                if i not in ct:more[level].append([path,i,ctf[i]])
                elif i not in ctf:less[level].append([path,i,ct[i]])
                else:circum(ct[i],ctf[i],level+1,path+i+"\\")
    circum(ct,ctf,0,"")
    return name,[more,less],get_tree(),ctf,ftc,infor

def dict_update(name,ctff,na,ct,infor,p=True):
    text=[["更新","删除"],["name\\","ctf\\"]]
    name.append([0,0])
    ctff.append([0,0])
    name=[name,ctff]
    #l{name,ctff}
    #k{"更新，删除"}
    #j[路径，name，子目录]
    for l in 0,1:
        for k in 0,1:
            for i in range(4):
                for j in name[l][k][i]:
                    if i==3:print(f"{c(12)}{text[0][k]}了{c(24)}{text[1][l]}{j[0]}{c(12)}目录下的{c(26)}{j[1]}{c(12)}文件")
                    else:
                        print(f"{c(12)}{text[0][k]}了{c(24)}{text[1][l]}{j[0]}{c(12)}目录下的{c(26)}{j[1]}{c(12)}分支,目录如下")
                        show(text[1][l]+j[0]+j[1],j[2],1)
                    name[l][2][k]+=1
    x=name[0][2]+ctff[2]
    dict_load("name",na)
    dict_load("ctf",ct)
    
    infor=info_process(infor)
    t=round(end_time(2),3)
    report(f"第{infor[4]}次更新完成")
    #print(f"更新参数为{x+infor[3:5]+[t]}")
    if p:print(f'''{c(13)}本次更新报告：
{c(12)}这是第{c(24)}{infor[4]}{c(12)}次更新
{c(12)}更新时间为{c(24)}{infor[3]}{c(12)}
{c(12)}总共更新时长{c(24)}{t}{c(12)}秒
{c(12)}在name目录下更新了{c(24)}{x[0]}{c(12)}项
{c(12)}在name目录下删除了{c(24)}{x[1]}{c(12)}项
{c(12)}在ctf目录下更新了{c(24)}{x[2]}{c(12)}项
{c(12)}在ctf目录下删除了{c(24)}{x[3]}{c(12)}项''')
    return infor

def update_check(lis,root=False):
    flag=True
    for i in lis:
        for j in i:
            if j:flag=False
    if root:return flag
    if not flag:
        flag=input("检测到WP库内容更改，是否更新(Y/N)?")
        if flag.lower() in ["y","yes"]:return True
    return False

#目录展示与打印(show)(┃┗┣)
def show(path,dic,root=0,ftc={}):
    path=path.split("\\")
    path[-1]=f"{c(26)}*{path[-1]}*"
    print(f"{c(16)}"+path[0])
    path=path[1:]
    def cir(dic,level=0):
        if level<len(path):return {path[level]:cir(dic,level+1)}
        else:return dic
    dic=cir(dic)
    ftc=cir(ftc)
    def prin(dic,a,level=0,ftc={}):
        di=list(dic)
        if cb in di:
            if level==3 and ftc:
                ftc=list(ftc)
                ftc.pop(di.index(cb))
            di.pop(di.index(cb))
        for j in range(len(di)):
            i=list(di)[j]
            if j==len(di)-1:
                if ftc and (i[-4:]==".txt" or i[-5:]==".docx"):print(f"{c(21)}{a}┗ {c(14)}{i} {c(25)}({ftc[j]})")
                else:print(f"{c(21)}{a}┗ {c(level+11)}{i}")
                a+="  "
            else:
                if ftc and (i[-4:]==".txt" or i[-5:]==".docx"):print(f"{c(21)}{a}┣ {c(14)}{i} {c(25)}({ftc[j]})")
                else:print(f"{c(21)}{a}┣ {c(level+11)}{i}")
                a+="┃ "
            if level<2+root:
                try:
                    if ftc:prin(dic[i],a,level+1,ftc[i])
                    else:prin(dic[i],a,level+1)
                except TypeError:pass
            a=a[:-2]
    if len(path)==1:root-=1
    prin(dic,"",0,ftc)
    print()

#目录查找(content_select)
def content_select(cont,roo=0,roott=0):
    rrrrrr=0
    if cont[-1]=="*":
        rrrrrr=1
        cont=cont[:-1]
    if cont in ["$",""]:
        x={"$":0,"":1}[cont]
        show("name",name,x)
        show("ctf",ctf,x,ftc)
    elif cont=="name":
        if rrrrrr:show("name",name,1)
        else:show("name",name,-1)
    elif cont=="ctf":
        if rrrrrr:show("ctf",ctf,1,ftc)
        else:show("ctf",ctf,-1,ftc)
    else:
        lis=[]
        report(f"正在查找{cont}...")
        def cir(name,path,count,root=1,level=0,ftc={}):
            for i in name:
                if i==cb:continue
                if (not roo and cont==i) or cont+".txt"==i or cont+".docx"==i or (cont==i and (cont[-4:]==".txt" or cont[-5:]==".docx")):
                    print(f'{c(12)}在{c(24)}{path}{c(12)}目录下查找到{c(26)}"{i}"',end="")
                    if level==3:
                        if roott:
                            flag=True
                            for f in roott:
                                if i==f[0] and path[5:]+"\\"==f[2]:
                                    flag=False
                                    print(f"\n{c(11)}该文件已在分支下")
                            if flag:
                                mode=input(f"\n{c(23)}是否添加此分支/文件(Y/N)?").lower()
                                if mode in ["y","yes"]:lis.append([i,path[5:]])
                        else:
                            mode=input(f"\n{c(23)}是否立即查看此文件(Y/N)?").lower()
                            if mode in ["y","yes"]:op(path[5:]+"\\"+i)
                    else:
                        print(f"{c(12)},目录如下：")
                        if rrrrrr:show(path+"\\"+i,name[i],2)
                        elif root:show(path+"\\"+i,name[i],1)
                        else:show(path+"\\"+i,name[i],1,ftc[i])
                    count+=1
                if level<2+root:
                    if not root:count=cir(name[i],path+"\\"+i,count,root,level+1,ftc[i])
                    else:count=cir(name[i],path+"\\"+i,count,root,level+1)
            return count
        count=cir(name,"name",0)
        if not roott:count=cir(ctf,"ctf",count,0,0,ftc)
        report(f"总共找到{count}个{cont}")
        if roott:return lis

#目录操作(content_operate)
def content_operate(path,namme,level):
    print()
    global ctf,ftc,name,infor
    def ctf_remove(i):
        pat=i[1]
        if i[0][-4:]==".txt":
            p=read_txt(i[2]+i[0])
            p.pop(p.index(f"${pat[0]}-{pat[1]}-{pat[2]}"))
            write_txt(p,i[2]+i[0])
        else:
            p=Document(i[2]+i[0])
            j=0
            while j<len(p.paragraphs):
                if p.paragraphs[j].text==f"${pat[0]}-{pat[1]}-{pat[2]}":
                    CT_P = p.paragraphs[j]._element
                    CT_P.getparent().remove(CT_P)
                else:j+=1
            p.save(i[2]+i[0])
    lis=[]
    def cir(path,level):
        if level==0:
            if cb in ctf[path[0]]:
                lis.append([cb,list(path),""])
            for i in ctf[path[0]]:
                cir(path+[i],level+1)
        elif level==1:
            if cb in ctf[path[0]][path[1]]:
                lis.append([cb,list(path),""])
            for i in ctf[path[0]][path[1]]:
                cir(path+[i],level+1)
        else:
            for i in range(len(ctf[path[0]][path[1]][path[2]])):
                lis.append([ctf[path[0]][path[1]][path[2]][i],list(path),ftc[path[0]][path[1]][path[2]][i]])
    cir(path+[namme],level)
    if level==0:show('ctf'+'\\'+namme,ctf[namme],1,ftc[namme])
    if level==1:show('ctf'+'\\'+path[0]+'\\'+namme,ctf[path[0]][namme],1,ftc[path[0]][namme])
    if level==2:show('ctf'+'\\'+'\\'.join(path)+'\\'+namme,ctf[path[0]][path[1]][namme],1,ftc[path[0]][path[1]][namme])
    help_txt=f'''{c(14)}请输入你的操作，格式为{c(23)}[操作序号]  [参数1] [参数2]（可选，中间用一个空格隔开） ...
{c(23)}0.{c(13)}查看本操作帮助及分支目录{c(11)}（无参数）
{c(23)}1.{c(13)}切换到其他分支{c(11)}({c(23)}参数1{c(11)}--{c(16)}分支名{c(11)}(只能操作一个分支)))
{c(23)}2.{c(13)}查看WP{c(11)}(进入操作界面再选择参数)
{c(23)}3.{c(13)}重命名{c(11)}({c(23)}参数1{c(11)}--分支想要更改的{c(16)}新名字{c(11)})
{c(23)}4.{c(13)}添加文件{c(11)}({c(23)}参数{c(11)}--想要添加的{c(16)}文件名{c(11)}(可以添加任意个文件)
{c(23)}5.{c(13)}删除分支内WP{c(11)}(进入操作界面再选择参数)
{c(23)}6.{c(13)}更改分支路径{c(11)}({c(23)}参数1{c(11)}--想要更改到的{c(16)}父分支名{c(11)})
{c(23)}7.{c(13)}删除分支{c(11)}（无参数）
{c(23)}8.{c(13)}退出{c(11)}（无参数）
{c(13)}注：重命名后若与其他分支名相同会自动合并
'''
    print(help_txt)
    while 1:
        mode=input(">")
        if not mode or (len(mode)==1 and not "0"<=mode[0]<="8") or (len(mode)>=2 and(not "0"<=mode[0]<="8" or mode[1]!=" ")):continue
        mode=mode.split(" ")
        if mode[0]=="0":
            print()
            if level==0:show('ctf'+'\\'+namme,ctf[namme],1,ftc[namme])
            if level==1:show('ctf'+'\\'+path[0]+'\\'+namme,ctf[path[0]][namme],1,ftc[path[0]][namme])
            if level==2:show('ctf'+'\\'+'\\'.join(path)+'\\'+namme,ctf[path[0]][path[1]][namme],1,ftc[path[0]][path[1]][namme])
            print(help_txt)
            continue
        elif mode[0]=="3":
            if len(mode)==1 or mode[1]=="":nam=input(f"{c(24)}请输入想要更改的名字，回车退出：{c(23)}")
            else:nam=mode[1]
            if nam=="":continue
            for i in lis:
                pat=list(i[1])
                i[1][level]=nam
                if i[0]==cb and len(i[1])<3:
                    p=read_txt(cb)
                    if len(i[1])==2:p[p.index(f"${pat[0]}-{pat[1]}")]=f"${i[1][0]}-{i[1][1]}"
                    if len(i[1])==1:p[p.index(f"${pat[0]}")]=f"${i[1][0]}"
                    write_txt(p,cb)
                else:
                    st=f"${i[1][0]}-{i[1][1]}-{i[1][2]}"
                    if i[0][-4:]==".txt":
                        p=read_txt(i[2]+i[0])
                        p[p.index(f"${pat[0]}-{pat[1]}-{pat[2]}")]=st
                        write_txt(p,i[2]+i[0])
                    else:
                        p=Document(i[2]+i[0])
                        for j in range(len(p.paragraphs)):
                            if p.paragraphs[j].text==f"${pat[0]}-{pat[1]}-{pat[2]}":p.paragraphs[j].text=st
                        p.save(i[2]+i[0])
            namme=nam
            print()
        if mode[0]=="4":
            while 1:
                if level==2:
                    st=f"${path[0]}-{path[1]}-{namme}"
                    if len(mode)==1:files=input(f"{c(24)}注1：也可以先输入目录进行查询，回车退出\n注2：同名文件易出bug\n请输入想要添加的文件名(多个可用空格隔开)：{c(23)}")
                    else:files=" ".join(mode[1:])
                    if not files:break
                    li=[]
                    for i in files.split(" "):
                        try:li+=content_select(i,0,lis)
                        except TypeError:continue
                        print()
                    for i in li:
                        if i[0][-4:]==".txt":
                            p=read_txt(i[1]+"\\"+i[0])
                            p.append(st)
                            write_txt(p,i[1]+"\\"+i[0])
                        else:
                            p=Document(i[1]+"\\"+i[0])
                            p.add_paragraph(st)
                            p.save(i[1]+"\\"+i[0])
                    print(f"{c(24)}总共添加了{len(li)}个文件")
                    mode=["4"]
                else:
                    if len(mode)==1:nam=input(f"{c(24)}回车退出\n请输入想要在此分支下新创建的分支名(多个可用空格隔开)：{c(23)}")
                    else:nam=" ".join(mode[1:])
                    if not nam:break
                    che=[]
                    for i in lis:
                        try:che.append(i[1][level+1])
                        except IndexError:continue
                    for i in nam.split(" "):
                        if i not in che:
                            if level==0:st=f"${namme}-{i}"
                            if level==1:st=f"${path[0]}-{namme}-{i}"
                            p=read_txt(cb)
                            p.append(st)
                            write_txt(p,cb)
                        else:print(f"{c(11)}{i}分支已存在")
                    mode=["4"]
            print()
        if mode[0]=="5":
            i=0
            while i<len(lis):
                if lis[i][0]==cb:lis.pop(i)
                else:i+=1
            for j in range(len(lis)):
                print(f"{c(23)}{j}.{c(14)}{lis[j][0]}  {c(25)}({lis[j][2]})")
            choose=input(f"{c(24)}\n请选择想要删除的文件的序号(用空格隔开)，回车退出：{c(23)}")
            if not choose:continue
            for i in choose.split(" "):
                try:ctf_remove(lis[int(i)])
                except ValueError:continue
            print()
        if mode[0]=="2":
            i=0
            while i<len(lis):
                if lis[i][0]==cb:lis.pop(i)
                else:i+=1
            while 1:
                for j in range(len(lis)):
                    print(f"{c(23)}{j}.{c(14)}{lis[j][0]}  {c(25)}({lis[j][2]})")
                choose=input(f"{c(24)}\n请选择想要查看的文件的序号(用空格隔开)，回车退出：{c(23)}")
                if not choose:break
                for i in choose.split(" "):
                    try:op(lis[int(i)][2]+"\\"+lis[int(i)][0])
                    except ValueError:continue
            print()
            continue
        if mode[0]=="1":
            if len(mode)==1:
                show("ctf",ctf)
                nam=input(f"{c(24)}可以用\"{c(26)}misc-签到{c(24)}\"的形式)\n请输入你想要转移到的分支：{c(26)}")
            else:nam=mode[1]
            return nam
        if mode[0]=="6":
            if level==0:
                print(f"{c(11)}本分支层级过高，无法转目录")
                continue
            if len(mode)==1:
                if level==1:show("ctf",ctf,-2)
                if level==2:show("ctf",ctf,-1)
                nam=input(f"{c(24)}(可以用\"{c(23)}misc-签到{c(24)}\"的形式)\n请选择该分支想要转到的目录：{c(23)}")
            else:nam=mode[1]
            if nam==path[-1]:
                print(f"{c(11)}该分支已经在{nam}目录下！")
                continue
            if not nam:
                print(f"{c(11)}要转到的目标目录不存在！")
                continue
            if "-" in nam:
                nam=nam.split("-")
                flag=nam[0]
                nam=nam[1]
            elif level==1 and nam not in ctf:
                print(f"{c(11)}要转到的目标目录不存在！")
                continue
            elif level==2:
                flag=0
                for i in ctf:
                    if nam in i:flag=i
                if not flag:
                    print(f"{c(11)}要转到的目标目录不存在！")
                    continue
            for i in lis:
                pat=list(i[1])
                if level==1:i[1][0]=nam
                if level==2:i[1]=[flag,nam,namme]
                if i[0]==cb and len(i[1])<3:
                    p=read_txt(cb)
                    if len(i[1])==2:p[p.index(f"${pat[0]}-{pat[1]}")]=f"${i[1][0]}-{i[1][1]}"
                    write_txt(p,cb)
                else:
                    st=f"${i[1][0]}-{i[1][1]}-{i[1][2]}"
                    if i[0][-4:]==".txt":
                        p=read_txt(i[2]+i[0])
                        p[p.index(f"${pat[0]}-{pat[1]}-{pat[2]}")]=st
                        write_txt(p,i[2]+i[0])
                    else:
                        p=Document(i[2]+i[0])
                        for j in range(len(p.paragraphs)):
                            if p.paragraphs[j].text==f"${pat[0]}-{pat[1]}-{pat[2]}":p.paragraphs[j].text=st
                        p.save(i[2]+i[0])
            if level==1:path=[nam]
            if level==2:path=[flag,nam]
            print()
        if mode[0]=="7":
            if len(mode)==1:choose=input(f"{c(24)}你确定要删除这个分支吗(Y/N)?{c(23)}").lower()
            else:choose=mode[1]
            if choose in ["y","yes"]:
                for i in lis:
                    path=i[1]
                    if i[0]==cb:
                        p=read_txt(cb)
                        if level==1:
                            st=f"${path[0]}"
                            if st not in p:p.append(st)
                        if level==2:
                            st=f"${path[0]}-{path[1]}"
                            if st not in p:p.append(st)
                        if len(path)==1:p.pop(p.index(f"${path[0]}"))
                        if len(path)==2:p.pop(p.index(f"${path[0]}-{path[1]}"))
                        if len(path)==3:p.pop(p.index(f"${path[0]}-{path[1]}-{path[2]}"))
                        write_txt(p,cb)
                    else:ctf_remove(i)
            else:continue
            up_A,up_B,name,ctf,ftc,infor=dict_check(name,ctf)
            infor=dict_update(up_A,up_B,name,ctf,infor,0)
            return 0
        if mode[0]=="8":return 0
        up_A,up_B,name,ctf,ftc,infor=dict_check(name,ctf)
        infor=dict_update(up_A,up_B,name,ctf,infor,0)
        try:
            if level==0:a=list(ctf[namme])
            if level==1:a=list(ctf[path[0]][namme])
            if level==2:a=list(ctf[path[0]][path[1]][namme])
        except KeyError:
            print(f"{c(23)}{namme}{c(21)}目录下不存在文件导致{c(23)}{namme}{c(21)}目录不存在，自动退出中...")
            return 0
        lis=[]
        cir(path+[namme],level)
    
if __name__=="__main__":
    try:
        begin_time(0)
        help_text=f'''
{c(14)}请输入你的操作，格式为{c(23)}[操作序号]  [参数1] [参数2]（可选，中间用一个空格隔开） ...
{c(23)}0-{c(13)}查看本操作帮助{c(11)}（无参数）
{c(23)}1-{c(13)}基本信息{c(11)}（无参数）
{c(23)}2-{c(13)}更新WP库{c(11)}（无参数）
{c(23)}3-{c(13)}查找分支/文件{c(11)}({c(23)}参数{c(11)}--{c(16)}分支/文件名{c(11)}(可以查找任意个分支/文件)(默认展开两层)({c(16)}${c(11)}展开三级目录,后缀{c(16)}*{c(11)}展开全部文件))
{c(23)}4-{c(13)}新建分支{c(11)}({c(23)}参数1{c(11)}--创建分支的{c(16)}父分支名{c(11)},{c(23)}参数2{c(11)}--创建的{c(16)}分支名{c(11)})
{c(23)}5-{c(13)}分支操作{c(11)}({c(23)}参数1{c(11)}--{c(16)}分支名{c(11)}(只能操作一个分支))(更名、扩展、拆分、合并)
{c(23)}注：可以直接输入分支或文件名进行查询
'''
        print(f'''
{c(23)} __        __    _ _       _   _         _         _   _ ____  _   _ _____ 
{c(13)} \ \      / / __(_) |_ ___| | | |_ __   (_)_ __   | \ | | __ )| | | |_   _|
{c(22)}  \ \ /\ / / '__| | __/ _ \ | | | '_ \  | | '_ \  |  \| |  _ \| | | | | |  
{c(16)}   \ V  V /| |  | | ||  __/ |_| | |_) | | | | | | | |\  | |_) | |_| | | |  
{c(24)}    \_/\_/ |_|  |_|\__\___|\___/| .__/  |_|_| |_| |_| \_|____/ \___/  |_|  
{c(24)}                                |_|                                        
{c(16)}--by 网安232易皓天  
>>>{c(14)}WriteUp in NBUT version "1.0.1" 2023-11-06''')
        #report("正在初始化...")
        
        if not "information.txt" in dir_file():
            report("检测到WP库未构建,正在构建...")
            begin_time(1)
            initial()
            if "网站" not in dir_file():new_folder("网站/ctfshow/菜狗杯")
            if "比赛" not in dir_file():new_folder("比赛")
            write_txt(["$misc-010-Ctrl+F"],"网站\\ctfshow\\菜狗杯\\杂项签到.txt")
            report(f"数据库构建完成，用时{round(end_time(1),3)}秒")
        #report("正在载入数据库...")
        begin_time(1)
        name=dict_load("name")
        ctf=dict_load("ctf")
        up_A,up_B,name,ctf,ftc,infor=dict_check(name,ctf)
        infor=dict_update(up_A,up_B,name,ctf,infor,0)
        report("数据库加载完成，用时%s秒"%round(end_time(1),3))
        print(help_text)
        while 1:
            mode=input(f"{c(23)}>>")
            if not mode:continue
            mode=mode.split(" ")
            if not "0"<=mode[0]<="5":mode.insert(0,"3")
            if mode[0]=="0":
                print(help_text+"\n")
            elif mode[0]=="1":
                report("正在查看WP库信息...")
                info_view(infor)
            elif mode[0]=="2":
                up_A,up_B,name,ctf,ftc,infor=dict_check(name,ctf)
                flag=True
                for i in up_A+up_B:
                    for j in i:
                        if j:flag=False
                if flag:report("更新检查完成，数据一致，无需更新")
                else:infor=dict_update(up_A,up_B,name,ctf,infor)
                print()
            elif mode[0]=="3":
                infor[8]+=1
                infor=info_process(infor)
                if len(mode)==1:files=input(f"{c(24)}请输入你想要查询的分支/文件名（多个可用空格隔开）：{c(23)}").split(" ")
                else:files=mode[1:]
                for i in files:
                    if i:content_select(i)
                    print()
                    
            elif mode[0]=="4":
                if len(mode)==1:
                    show("ctf",ctf,-1)
                    pos=input(f"{c(24)}(可以用\"{c(23)}misc-签到{c(24)}\"的形式)\n请选择你要创建新分支的位置：{c(23)}")
                    nam=input(f"{c(24)}请输入你想要新建的分支名：{c(23)}")
                elif len(mode)==2:
                    pos=mode[1]
                    nam=input(f"{c(24)}请输入你想要新建的分支名：{c(23)}")
                elif len(mode)==3:
                    pos=mode[1]
                    nam=mode[2]
                flag=False
                if "-" in pos:
                    pos=pos.split("-")
                    if pos[0] in ctf and pos[1] in ctf[pos[0]]:
                        if nam in ctf[pos[0]][pos[1]]:print(f"{c(11)}该分支已经存在！")
                        else:
                            add_txt([f"${pos[0]}-{pos[1]}-{nam}"],cb)
                            flag=True
                    else:print(f"{c(11)}找不到你想要创建新分支的位置")
                elif pos=="ctf":
                    if nam in ctf:print(f"{c(11)}该分支已经存在！")
                    else:
                        add_txt([f"${nam}"],cb)
                        flag=True
                elif pos in ctf:
                    if nam in ctf[pos]:print(f"{c(11)}该分支已经存在！")
                    else:
                        add_txt([f"${pos}-{nam}"],cb)
                        flag=True
                else:
                    che=0
                    for i in ctf:
                        if pos in ctf[i]:
                            if nam in ctf[i][pos]:print(f"{c(11)}该分支已经存在！")
                            else:
                                add_txt([f"${i}-{pos}-{nam}"],cb)
                                flag=True
                            che=1
                    if not che:print(f"{c(11)}找不到你想要创建新分支的位置")
                if flag:
                    up_A,up_B,name,ctf,ftc,infor=dict_check(name,ctf)
                    infor=dict_update(up_A,up_B,name,ctf,infor,0)
            elif mode[0]=="5":
                if len(mode)==1:
                    show("ctf",ctf)
                    nam=input(f"{c(24)}可以用\"{c(26)}misc-签到{c(24)}\"的形式)\n请输入你想要操作的分支：{c(26)}")
                else:nam=mode[1]
                while nam:
                    if "-" in nam:
                        nam=nam.split("-")
                        if len(nam)==2 and nam[0] in ctf and nam[1] in ctf[nam[0]]:
                            nam=content_operate([nam[0]],nam[1],1)
                        elif len(nam)==3 and nam[0] in ctf and nam[1] in ctf[nam[0]] and nam[2] in ctf[nam[0]][nam[1]]:
                            nam=content_operate(nam[0:2],nam[2],2)
                        else:
                            print(f"{c(11)}找不到你想要操作的分支")
                            break
                    elif nam=="ctf":
                        print(f"{c(11)}无法对根目录进行操作")
                        break
                    else:
                        che=1
                        for i in ctf:
                            if nam==i and che:
                                nam=content_operate([],i,0)
                                che=0
                                break
                            for j in ctf[i]:
                                if nam==j and che:
                                    nam=content_operate([i],j,1)
                                    che=0
                                    break
                                for k in ctf[i][j]:
                                    if nam==k and che:
                                        nam=content_operate([i,j],k,2)
                                        che=0
                                        break
                                if not nam:break
                            if not nam:break
                        if che:
                            print(f"{c(11)}找不到你想要操作的分支")
                            break
    except Exception as e:
        error_type = type(e).__name__  # 获取错误类型
        error_msg = str(e)  # 获取错误消息
        traceback.print_exc()  # 打印异常追踪信息
        traceback.print_exc(file=open('log.txt','a'))
        while 1:
            input("程序出错:请将报错信息及之前运行的内容截图并联系开发者")
